@node POSIX signals
@section Signals

@stindex posix-signals
There are two varieties of signals available, named & anonymous.  A
@dfn{named} signal is one for which there is provided a symbolic name,
such as @code{kill} or @code{pipe}.  Anonymous signals are those that
the operating system provided but for which POSIX does not define a
symbolic name, only a number, and which may not have meaning on other
operating systems.  Named signals preserve their meaning through heap
image dumps; anonymous signals may not be dumped in heap images.  (If
they are, a warning is signalled, and they are replaced with a special
token that denotes a non-portable signal.)  Not all named signals are
available from all operating systems, and there may be multiple names
for a single operating system signal number.

@deffn syntax signal name @returns{} signal
@deffnx procedure name->signal symbol @returns{} signal or @code{#f}
@deffnx procedure integer->signal integer @returns{} signal
@deffnx procedure signal? object @returns{} boolean
@deffnx procedure signal-name signal @returns{} symbol or @code{#f}
@deffnx procedure signal-os-number signal @returns{} integer
@deffnx procedure signal=? signal@suba{a} signal@suba{b} @returns{} boolean
@code{Signal} evaluates to the signal object with the known symbolic
name @var{name}.  It is an error if @var{name} is not recognized as any
signal's name.  @code{Name->signal} returns the signal corresponding
with the given @var{name} or @code{#f} if no such signal is known.
@code{Integer->signal} returns a signal, named or anonymous, with the
given OS number.  @code{Signal?} is the disjoint type predicate for
signal objects.  @code{Signal-name} returns the symbolic name of
@var{signal} if it is a named signal or @code{#f} if it is an anonymous
signal.  @code{Signal-OS-number} returns the operating system's integer
value of @var{signal}.  @code{Signal=?} tests whether two signals are
the same, @ie{} whether their OS numbers are equal equal.

These are all of the symbols that POSIX defines.

@table @code
@item abrt
abnormal termination (as by @code{abort(3)})
@item alrm
timeout signal (as by @code{alarm(2)})
@item fpe
floating point exception
@item hup
hangup on controlling terminal or death of controlling process
@item ill
illegal instruction
@item int
interrupt --- interaction attention
@item kill
termination signal, cannot be caught or ignored
@item pipe
write was attempted on a pipe with no readers
@item quit
interaction termination
@item segv
segmentation violation --- invalid memory reference
@item term
termination signal
@item usr1
@itemx usr2
for use by applications
@item chld
child process stopped or terminated
@item cont
continue if stopped
@item stop
stop immediately, cannot be caught or ignored
@item tstp
interactive stop
@item ttin
read from control terminal attempted by a background process
@item ttou
write to control terminal attempted by a background process
@item bus
bus error --- access to undefined portion of memory
@end table

There are also several other signals whose names are allowed to be
passed to @code{signal} that are not defined by POSIX, but that are
recognized by many operating systems.

@table @code
@item trap
trace or breakpoint trap
@item iot
synonym for @code{abrt}
@item emt
@item sys
bad argument to routine (SVID)
@item stkflt
stack fault on coprocessor
@item urg
urgent condition on socket (4.2 BSD)
@item io
I/O now possible (4.2 BSD)
@item poll
synonym for @code{io} (System V)
@item cld
synonym for @code{chld}
@item xcpu
CPU time limit exceeded (4.2 BSD)
@item xfsz
file size limit exceeded (4.2 BSD)
@item vtalrm
virtual alarm clock (4.2 BSD)
@item prof
profile alarm clock
@item pwr
power failure (System V)
@item info
synonym for @code{pwr}
@item lock
file lock lost
@item winch
Window resize signal (4.3 BSD, Sun)
@item unused
@end table
@end deffn

@subsection Sending & receiving signals

@deffn procedure signal-process pid signal @returns{} unspecified
Sends a signal represented by @var{signal} to the process identified by
@var{pid}.
@end deffn

@cindex signal queues
Signals received by the Scheme process can be obtained via one or more
@dfn{signal queues}.  Each signal queue has a list of monitored signals
and a queue of received signals that have yet to be consumed from the
queue.  When the Scheme process receives a signal, that signal is added
to the signal queues that are currently monitoring the signal received.

@deffn procedure make-signal-queue signal-list @returns{} signal-queue
@deffnx procedure signal-queue? object @returns{} boolean
@deffnx procedure signal-queue-monitored-signals signal-queue @returns{} signal-list
@deffnx procedure dequeue-signal! signal-queue @returns{} signal (may block)
@deffnx procedure maybe-dequeue-signal! signal-queue @returns{} signal or @code{#f}
@code{Make-signal-queue} returns a new signal queue that will monitor
all of the signals in the given list.  @code{Signal-queue?} is the
disjoint type predicate for signal queues.
@code{Signal-queue-monitored-signals} returns a freshly-allocated list
of the signals currently monitored by @var{signal-queue}.
@code{Dequeue-signal!} & @code{maybe-dequeue-signal!} both access the
next signal ready to be read from @var{signal-queue}.  If the signal
queue is empty, @code{dequeue-signal!} will block until a signal is
received, while @code{maybe-dequeue-signal!} will immediately return
@code{#f}.
@end deffn

@strong{Note:} There is a bug in the current system that causes an
erroneous deadlock to occur if threads are blocked waiting for signals
and no other threads are available to run.  A workaround is to create a
thread that sleeps for a long time, which prevents any deadlock errors
(including real ones):

@lisp
> ,open threads
> (spawn (lambda ()
           ;; Sleep for a year.
           (sleep (* 1000 60 60 24 365))))@end lisp

@deffn procedure add-signal-queue-signal! signal-queue signal @returns{} unspecified
@deffnx procedure remove-signal-queue-signal! signal-queue signal @returns{} unspecified
These add & remove signals from signal queues' list of signals to
monitor.  Note that @code{remove-signal-queue-signal!} also removes any
pending signals from the queue, so @code{dequeue-signal!} &
@code{maybe-dequeue-signal!} will only ever return signals that are
on the queue's list of monitored signals when they are called.
@end deffn
